….
Ordem dos filmes: The Matrix, The Matrix: Reloaded, The Matrix: Revolutions.
Escolhi falar aqui sobre uma das minhas trilogias favoritas: Matrix. Esse filme que mistura muito Sci-fi com Ação, muitas artes marciais, cenas surreais envolvendo desvios de balas, além de para-las no ar tem várias interpretações diferentes, sobre como o homem fica imerso na sociedade a ponto de ser apenas uma bateria descartável para ela. Outras interpretações ainda falam sobre a forma como o homem está submisso a sociedade de consumo e como isso irá destruir o nosso mundo, como a realidade que eles vivem no filme e ainda que o filme é um Conto da caverna (Platão) contemporâneo.
Seja qual a interpretação que for é uma trilogia muito bem fechada com roteiro excelente e elenco ainda melhor. Uma verdadeira história do Homem vs Maquina e o Homem contra ele mesmo, suas dúvidas e principalmente as consequências das suas escolhas.
….
Para o tratamento inicial dos dados temos que isolar os filmes dessa trilogia do restante dos filmes. Entretanto já pensando nas próximas sessões, que serão comparativos gerais, a ideia é criar uma nova coluna contendo o número de gêneros naquele filme em questão pois, isso facilitará na hora de fazermos comparação de média e distribuição de notas depois.
Apesar de existirem 4 arquivos com os dados dos filmes, para esse laboratório, só foi necessário dois deles: ratings e movies.
As informações mais relevantes de ratings eram principalmente o id do filme (movieId) e o próprio voto dos usuários (rating). Já para o movies as principais eram o tÃtulo do filme (title), o id do filme também (movieId) e os gêneros os quais o filme se encaixa (genres).
Então os dois csv foram usados para formar um novo dataframe que contém as informações dos dois antigos, chamado merged. Esse df também foi usado para a criação da nova coluna com a quantidade de gêneros. Todas as variações abaixo só foram colunas que precisavam ter formatos diferentes dos dados.
links <- read.csv("dados/links.csv")
movies.factor <- read.csv("dados/movies.csv")
ratings <- read.csv("dados/ratings.csv")
tags <- read.csv("dados/tags.csv")
movies.str <- read_csv("dados/movies.csv", col_types = cols(genres = col_character()))
merged <- merge(ratings,movies.factor,by = "movieId")
merged.str <- merge(ratings,movies.str,by = "movieId")
matrix.trilogia <- merged[grep("Matrix", merged$title), ]
means <- matrix.trilogia %>%
select(title,rating)
names(means)[1] <- "title"
names(means)[2] <- "rating"
means <- means %>%
group_by(title) %>%
mutate(rating = mean(rating))
means <- means[match(unique(means$title),means$title),]
numero_generos.completo <- merged.str %>%
mutate(n_generos = vapply(strsplit(merged.str$genres, "\\W+"), length, integer(1)))
Vamos analisar primeiramente a variação das notas e suas medianas para essa trilogia, e comprovar de vez qual o filme que os usuários mais gostam e consequentemente deram melhores notas.
O primeiro gráfico para ajudar nesse estudo é o boxplot. Aqui existe um para cada filme da trilogia, e já podemos comprovar o que em casos de muitos outros filmes é verdadeiro: O primeiro filme é o mais impactante.
O primeiro filme tem a mediana maior que os outros dois e isso é facil de entender pois, o filme foi muito inovador para a época, além de trazer uma ideia muito extrema de mundo pós-apocaliptico misturado com ação/artes marciais. Isso chocou muitas pessoas na época que acharam o filme uma verdadeira revolução do cinema. Entretanto esse hype causou a queda das notas nos outros dois filmes que se esperava que fosse tão inovador quanto o primeiro, so que os criadores mantiveram a mesma ideia.
matrix.trilogia %>%
ggplot(aes(x=title,y=rating, group = title, color = title)) + geom_boxplot() + coord_flip()
Outra forma de vermos as mesmas variáveis mas para analisarmos outro aspecto é o Violinplot.
Nesse tipo de gráfico vemos principalmente onde os pontos, que correspondem as notas, se concentram e podemos ver se os usuários votaram de forma equilibrada ou apenas alguns que deram notas baixas, o mesmo se aplicanto a notas altas.
A conclusão desse gráfico é que para o primeiro filme vemos a concentração de pontos acima da nota 3, o que não é o mesmo comportamento do ultimo filme (The Matrix: Revolutions), o qual tem uma distribuição quase uniforme durante o eixo X todo. Isso mostra que os usuários divergiram muito de opinião sobre o quão bom foi o filme.
matrix.trilogia %>%
ggplot(aes(x=title,y=rating, group = title, color = title)) + geom_violin() + coord_flip()
Nos gráficos anteriores estávamos focados apenas na mediana e na distribuição das notas mas a média também é um fator importante a ser analisado, por isso o gráfico de barras é util para estudarmos esse fator.
Esse gráfico nos mostra uma diferença bem menor que nos anteriores, principalmente quando vemos em relação ao segundo e ao terceiro filme. Os dois tem um comportamento bem parecido, mas o primeiro ainda continua bem a frente nos votos.
means %>%
ggplot(aes(x=title, y=rating, color = title)) + geom_col() + geom_point() + coord_flip()
A parte que importa realmente é agora: Mas e se um novo voto viesse de um usuário? Qual intervalo ele se encaixaria em cada um dos filmes da trilogia?
Para calcular esse intervalo de confiança (IC ou CI em inglês) precisamos calcular a média (que já possuimos da sessão anterior) a variância e consequentemente o desvio padrão. Podemos também calcular o Erro padrão que é basicamente uma medida estatÃstica muito parecida com o desvio padrão só que indica a diferença da amostra para a população real da variável.
Aqui temos os dados sumarizados em que sd corresponde ao desvio padrão, se o erro padrão e ci o nosso intervalo de confiança (95%), além disso rating passa a ser média como no ultimo gráfico da sessão anterior. Podemos observar aqui que o ci diminui a medida que o N aumenta, e por que isso?
A medida que a amostra se aproxima da população, ou seja, cresce, o erro diminui e então a média amostral que temos a partir desse dataset pequeno se aproxima da verdadeira média populacional.
matrix.trilogia$title <- as.character(matrix.trilogia$title)
matrix.trilogia$title <- as.factor(matrix.trilogia$title)
matrix.resumed <- Rmisc::summarySE(matrix.trilogia, measurevar="rating", groupvars=c("title"))
pd <- position_dodge(0.1) # move them .05 to the left and right
print(matrix.resumed, row.names = FALSE)
## title N rating sd se
## Matrix Reloaded, The (2003) 82 3.268293 1.0219659 0.11285726
## Matrix Revolutions, The (2003) 54 3.037037 0.9993009 0.13598763
## Matrix, The (1999) 259 4.183398 0.9012021 0.05599797
## ci
## 0.2245505
## 0.2727567
## 0.1102713
Podemos ver que o intervalo de confiança como essas barras paralelas ao eixo X que estão ao redor dos pontos que representam os filmes. Note o tamanho do intervalo é proporcional ao IC, consequentemente a falta de precisão é muito maior nos dois ultimos filmes do que em relação ao primeiro.
ggplot(matrix.resumed, aes(x=title, y=rating, colour=title)) +
geom_errorbar(aes(ymin=rating-ci, ymax=rating+ci), width=.1, position=pd) +
geom_line(position=pd) +
geom_point(position=pd) +
ylab("Rating") +
scale_y_continuous(breaks=seq(0,6, by=0.5)) + coord_flip()
## geom_path: Each group consists of only one observation. Do you need to
## adjust the group aesthetic?
Já aqui podemos ver através de gráficos de barras o mesmo comportamento só que com uma visualização diferente.
Nesse primeiro plot a variável que foi somada (e subtraida) da média foi o erro padrão, a qual já foi explicada anteriormente. Note que ela é diretamente proporcional ao intervalo de confiança, os dois são muito parecidos, mas inversamente proporcional a quantidade de avaliações dos filmes.
ggplot(matrix.resumed, aes(x=title, y=rating, fill=title)) +
geom_bar(position=position_dodge(), stat="identity") +
geom_errorbar(aes(ymin=rating-se, ymax=rating+se),
width=.2, # Width of the error bars
position=position_dodge(.9))
Mesmo gráfico anterior só que aqui vemos o intervalo de confiança e não o erro padrão.
ggplot(matrix.resumed, aes(x=title, y=rating, fill=title)) +
geom_bar(position=position_dodge(), stat="identity") +
geom_errorbar(aes(ymin=rating-ci, ymax=rating+ci),
width=.2, # Width of the error bars
position=position_dodge(.9))
Analisar os dados da sua trilogia favorita é muito bom, mas faz crescer um pensamento sobre os filmes em geral: Será que existe alguma quantidade de gêneros em que um filme se encaixa que isso faz ele receber notas melhores?
É dedicado a esse questionamento que essa sessão foi criada e foi necessário a criação de uma nova coluna no dataframe que está sendo manipulado pois, o ideal é termos o número de gêneros para cada filmes/avaliação e não o nome do gênero em si.
Dentro do dataframe foi criada a colune n_generos que contêm a quantidade de gêneros que o filme se encaixa, e essa variável é chave para essa análise a seguir. Os limite inferior dessa variável é 1 e o superior é 11.
Seguindo o raciocÃnio da sessão anterior podemos ver primeiramente como se comportam as notas em relação a cada quantidade de gêneros, mediana, quartis e a distribuição durante o eixo de forma interativa com esse boxplot.
Primeiramente vamos desconsiderar a quantidade de gêneros que só aparecem em um filme (caso do 9, 10 e 11) e analisarmos o resto. Podemos ver que o que tem a maior mediana e concentração de votos na parte superior do eixo é quando n_generos é igual a 8. Para o resto dos valores o comportamento é muito parecido, chegando a ser identico para 1 a 4 e 6, 5 e 7.
ggplotly(numero_generos.completo %>%
ggplot(aes(x=n_generos,y=rating, group = n_generos)) + geom_boxplot() + scale_x_continuous(breaks=seq(0, 12, by=1)))
Agora que sabemos qual a quantidade de generos em um filme que é melhor votada, podemos avaliar se é uma votação justa, do ponto de vista de quantidade de votos. Podemos fazer esse comparativo para quando n_generos é igual a 8 ou a 1, que neste ultimo caso são os filmes que tem apenas um gênero. Para isso utilizaremos dois gráficos de barra divididos por essa categoria citada anteriormente mas que no eixo X é especificamente cada nota e no Y é a quantidade de votos daquela nota.
Para poder visualizar melhor nesse gráfico você talvez queira clicar em Autoscale pois a quantidade de filmes com 8 gêneros é absurdamente menor do que com apenas 1. Podemos observar aqui que a quantidade de votos para os filmes com 1 gênero é muito maior e isso pode ser um dos colaboradores principais para que a nota baixe.
generos.8.e.1 <- numero_generos.completo %>%
filter(n_generos == 8| n_generos == 1)
generos.8.e.1$n_generos <- as.factor(generos.8.e.1$n_generos)
generos.8.e.1$rating <- as.factor(generos.8.e.1$rating)
ggplotly(generos.8.e.1 %>%
ggplot(aes(x=rating, fill = n_generos)) + geom_histogram(aes(y=..count..), stat = "count") + facet_grid(n_generos~.)
)
Podemos também usar a média para comparar como se comportam essas mesmas classes de filmes. A ideia é usar um gráfico comum de barrar para a associação ser mais rápida e facil.
O resultado foi um surpreendente. A expectativa é que essa média para os filmes com apenas um gênero e subisse ainda mais para filmes com 8. Entretanto vemos que as duas médias se aproximaram, diferindo apenas por 0.4 pontos.
means.8.e.1 <- numero_generos.completo %>%
select(rating,n_generos)
means.8.e.1$n_generos <- as.factor(means.8.e.1$n_generos)
means.8.e.1 <- means.8.e.1 %>%
filter(n_generos == "1" | n_generos == "8") %>%
group_by(n_generos) %>%
mutate(rating = mean(rating))
means.8.e.1 <- means.8.e.1[match(unique(means.8.e.1$n_generos),means.8.e.1$n_generos),]
means.8.e.1 %>% ggplot(aes(x=n_generos,y=rating, color = n_generos, fill = n_generos)) + geom_bar(stat="identity")
Após todas essas análises podemos pensar se existe mesmo uma relação entre a quantidade de gêneros em um filmes e as notas que ele recebe. Para isso podemos utilizar os dados completos novamente e tentar cruzar as variáveis procurando uma correlação forte entre elas
Como resultado temos que a correlação é muito fraca, isso quer dizer que não necessariamente um filme que tem muitos gêneros vai ter boas avaliações. Pelo menos esses dados não comprovam isso.
means.8.e.1$n_generos <- as.numeric(means.8.e.1$n_generos)
numero_generos.completo %>%
select(-title,-genres,-timestamp,-movieId, -userId) %>%
ggpairs(cardinality_threshold = 2800)
Para os dados gerais que é ainda melhor de analisarmos e fazermos inferências, pois aqui temos os representantes de cada uma das quatidades de gêneros dos filmes. E podemos notar já na sumarização que o intervalo de confiança dos primeiros 4 elementos é muito pequeno, pela sua imensa quantidade de avaliações, notas dadas pelos usuários. Consequentemente olhamos para o erro padrão que também é muito pequeno em relação ao que estava sendo analisado antes com a trilogia de Matrix.
Aqui as colunas contém as mesmas variáveis que foram explicadas anteriormente para a análise dos filmes de Matrix.
numero_generos.completo$n_generos <- as.character(numero_generos.completo$n_generos)
generos.resumed <- Rmisc::summarySE(numero_generos.completo, measurevar="rating", groupvars=c("n_generos"))
generos.resumed <- na.omit(generos.resumed)
print(generos.resumed, row.names = FALSE)
## n_generos N rating sd se ci
## 1 17520 3.511444 1.064436 0.008041787 0.01576270
## 2 27430 3.557182 1.069542 0.006457803 0.01265762
## 3 25689 3.542645 1.047699 0.006536766 0.01281243
## 4 17908 3.569578 1.055512 0.007887508 0.01546028
## 5 8426 3.508248 1.053984 0.011482148 0.02250783
## 6 2491 3.559615 1.012353 0.020283601 0.03977446
## 7 405 3.438272 1.097315 0.054526038 0.10719019
## 8 132 3.931818 0.920033 0.080078597 0.15841457
Nestri gráfico de barras podemos visualizar o quão pequeno são os intervalos de confiança dos filmes que tem menos gêneros em relação aos que têm mais gêneros, por causa justamente da sua maior amostragem. Assim podemos concluir que o intervalo de confiança é quase desprezivel para esses casos, do 1 ao 5.
pd <- position_dodge(0.1) # move them .05 to the left and right
ggplot(generos.resumed, aes(x=n_generos, y=rating, fill=n_generos)) +
geom_bar(position=position_dodge(), stat="identity") +
geom_errorbar(aes(ymin=rating-ci, ymax=rating+ci),
width=.2, # Width of the error bars
position=position_dodge(.9))
Este scatterplot é um pouco mais dramático, entretanto ajuda bastante a perceber essa diferença acima citada, e principalmente do deslocamente e distância das médias dos votos dos usuários entre as diferentes categorias de gêneros.
numero_generos.completo$n_generos <- as.numeric(numero_generos.completo$n_generos)
generos.resumed <- Rmisc::summarySE(numero_generos.completo, measurevar="rating", groupvars=c("n_generos"))
generos.resumed <- na.omit(generos.resumed)
ggplot(generos.resumed, aes(x=n_generos, y=rating, colour=n_generos)) +
geom_errorbar(aes(ymin=rating-ci, ymax=rating+ci), width=.1, position=pd) +
geom_line(position=pd) +
geom_point(position=pd) + scale_x_continuous(breaks = seq(1,9,by=1))